﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using XDeal.DAL.Entities;
using Utility;
using XDeal.DAL.CustomEntities;
using Utility.Enums;

namespace XDeal.DAL.Implements
{
    public class DealDAO : BaseDAO
    {
        public DealDAO()
            : base()
        { }

        public IQueryable<Deal> IQueryableDeal()
        {
            return XDealDataContext.Deals.OrderBy(m => m.ID_i);
        }

        #region GET BASIC
        /// <summary>
        /// Get All Deal
        /// </summary>
        /// <returns>List of Deals</returns>
        public List<Deal> GetAll()
        {
            return XDealDataContext.Deals.ToList<Deal>();
        }

        /// <summary>
        /// Get Deal by ID
        /// </summary>
        /// <param name="ID">Deal ID</param>
        /// <returns>One Deal</returns>
        public Deal GetByID(int ID)
        {
            return XDealDataContext.Deals.Where(ob => ob.ID_i == ID).FirstOrDefault<Deal>();
        }
        #endregion

        #region GET ADVANCE
        /// <summary>
        /// Get List Of Deals By Status
        /// </summary>
        /// <param name="currPage">Current Page</param>
        /// <param name="itemPerpage">Items Per Page</param>
        /// <param name="totalItems">Total Items</param>
        /// <param name="status">Status</param>
        /// <returns>List Of Deal</returns>
        public List<Deal> GetAllDealByStatus(int currPage, int itemPerpage, ref int totalItems, DealStatus status)
        {
            int iStatus = ConvertManage.ConvertToInt(status, 3);
            var query = IQueryableDeal().Where(ob => ob.Status_i == iStatus).OrderBy(ob => ob.DisplayOder_i).ThenByDescending(ob => ob.DateAdded_dt);
            if (status == DealStatus.Open)
            {
                query = IQueryableDeal().Where(ob => ob.Status_i == iStatus && ob.EndDate_dt > DateTime.Now && ob.StartDate_dt <= DateTime.Now && ob.OrderDetails.Count < ob.CurrentQuantity_i && ob.IsPublish_b == true).OrderBy(ob => ob.DisplayOder_i).ThenByDescending(ob => ob.DateAdded_dt);
            }                
            return GetPager(query, currPage, itemPerpage, ref totalItems);
        }

        /// <summary>
        /// Get All List Of Deal For FrontEnd
        /// </summary>
        /// <param name="currPage">Current Page</param>
        /// <param name="itemPerpage">Item Per Page</param>
        /// <param name="totalItems">Total Items</param>
        /// <returns>List Of Deals</returns>
        public List<Deal> GetAllDealFrontEnd(int currPage, int itemPerpage, ref int totalItems)
        {
            int iStatus = ConvertManage.ConvertToInt(DealStatus.Waiting, 3);
            var query = IQueryableDeal().Where(ob => ob.Status_i != iStatus && ob.StartDate_dt <= DateTime.Now && ob.IsPublish_b == true).OrderBy(ob => ob.DisplayOder_i).ThenByDescending(ob => ob.DateAdded_dt);
            return GetPager(query, currPage, itemPerpage, ref totalItems);
        }

        private List<Deal> GetPager(IQueryable<Deal> data, int currPage, int itemPerPage, ref int totalItems)
        {
            totalItems = data.Count();
            if (currPage <= 0)
                currPage = 1;
            int totalPage = (totalItems % itemPerPage == 0) ? (totalItems / itemPerPage) : (totalItems / itemPerPage + 1);
            if (currPage > totalPage)
                currPage = totalPage;
            return data.Skip((currPage - 1) * itemPerPage).Take(itemPerPage).ToList<Deal>();
        }

        /// <summary>
        /// Get Valid Deal By ID. Valid = Publish | Not in Waiting for approval
        /// </summary>
        /// <param name="ID"></param>
        /// <returns></returns>
        public Deal GetValidDealByID(int ID)
        {
            int iStatus = ConvertManage.ConvertToInt(DealStatus.Waiting, 3);
            return XDealDataContext.Deals.Where(ob => ob.ID_i == ID && ob.StartDate_dt <= DateTime.Now && ob.IsPublish_b == true && ob.Status_i != iStatus).FirstOrDefault<Deal>(); 
        }

        #endregion

        #region INSERT, UPDATE, DELETE
        /// <summary>
        /// Insert Deal
        /// </summary>
        /// <param name="ob">Deal Object</param>
        /// <returns>True: Successful | False: Fail</returns>
        public bool Insert(Deal ob)
        {
            try
            {
                XDealDataContext.AddToDeals(ob);
                XDealDataContext.SaveChanges();
                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// Update Deal by Object
        /// </summary>
        /// <param name="ob">Deal Object</param>
        /// <returns>True: Successful | False: Fail</returns>
        public bool Update(Deal ob)
        {
            try
            {
                Deal _ob = GetByID(ob.ID_i);
                if (_ob != null)
                {
                    XDealDataContext.ApplyCurrentValues(_ob.EntityKey.EntitySetName, ob);
                    XDealDataContext.SaveChanges();
                    return true;
                }
                else
                    return false;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// Delete Deal by Object
        /// </summary>
        /// <param name="ob">Deal Object</param>
        /// <returns>True: Successful | False: Fail</returns>
        public bool Delete(Deal ob)
        {
            try
            {
                Deal _ob = GetByID(ob.ID_i);
                if (_ob != null)
                {
                    XDealDataContext.DeleteObject(_ob);
                    XDealDataContext.SaveChanges();
                    return true;
                }
                else
                    return false;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// Delete By ID
        /// </summary>
        /// <param name="ID">Deal ID</param>
        /// <returns>True: Successful | False: Fail</returns>
        public bool Delete(int ID)
        {
            try
            {
                Deal _ob = GetByID(ID);
                if (_ob != null)
                {
                    XDealDataContext.DeleteObject(_ob);
                    XDealDataContext.SaveChanges();
                    return true;
                }
                else
                    return false;
            }
            catch
            {
                return false;
            }
        }
        #endregion
    }
}
